﻿Public Structure Location
    Implements IEquatable(Of Location), IComparable(Of Location)

    Public Sub New(ByVal index As Integer, ByVal line As Integer, ByVal column As Integer)
        m_index = index
        m_line = line
        m_column = column
    End Sub

    Public Function CompareTo(ByVal other As Location) As Integer Implements IComparable(Of Location).CompareTo
        Dim lineDiff = Line - other.Line
        If lineDiff > 0 Then
            Return 1
        ElseIf lineDiff < 0 Then
            Return -1
        End If

        'same line, compare column
        Dim columnDiff = Column - other.Column
        If columnDiff > 0 Then
            Return 1
        ElseIf columnDiff < 0 Then
            Return -1
        Else

            'same line, same column.
            Return 0
        End If
    End Function

    Public Overloads Function Equals(ByVal other As Location) As Boolean Implements IEquatable(Of Location).Equals
        Return Index = other.Index AndAlso Line = other.Line AndAlso Column = other.Column
    End Function

    Private m_line As Integer
    Public ReadOnly Property Line() As Integer
        Get
            Return m_line
        End Get
    End Property

    Private m_column As Integer
    Public ReadOnly Property Column() As Integer
        Get
            Return m_column
        End Get
    End Property

    Private m_index As Integer
    Public ReadOnly Property Index() As Integer
        Get
            Return m_index
        End Get
    End Property

    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        If obj Is Nothing Then Return False
        Dim other = DirectCast(obj, Location)

        Return Equals(other)
    End Function

    Public Overrides Function ToString() As String
        Return String.Format("(Index: {0}, line: {1}, column: {2})", Index, Line, Column)
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return Line Xor Column << 4 Xor Index << 8
    End Function

End Structure
